package eerbaar.internal.level;

import eerbaar.context.IContext;
import eerbaar.level.IComplete;
import eerbaar.level.IHints;
import eerbaar.level.ILevel;
import eerbaar.level.IMessages;
import eerbaar.level.IStartup;
import eerbaar.level.IState;
import eerbaar.level.IStates;
import eerbaar.shared.message.DebugMsg;
import eerbaar.shared.message.MsgHelper;

public class Level implements ILevel {

    private final String goal;
    private final int index;
    private IContext model;
    private IState state;
    private IComplete complete = new Complete();
    private IMessages messages = new Messages();
    private IStartup startup = new Startup();
    private IStates states = new States();
    private IHints hints = new Hints();

    public Level(int index, String goal) {
        this.index = index;
        this.goal = goal;
    }

    @Override
    public boolean check() {

        if (this.model == null) {

            return false;
        }

        if (this.state != null) {

            boolean c = this.state.check();
            if (c) {
                this.state = nextState();
            }
        }

        return this.complete.execute(this.model);
    }

    @Override
    public IComplete getComplete() {
        return this.complete;
    }

    @Override
    public String getGoal() {
        return this.goal;
    }

    @Override
    public IHints getHints() {
        return this.hints;
    }

    @Override
    public int getIndex() {
        return this.index;
    }

    @Override
    public IMessages getMessages() {
        return this.messages;
    }

    @Override
    public IStartup getStartup() {
        return this.startup;
    }

    @Override
    public IStates getStates() {
        return this.states;
    }

    public IState nextState() {

        IState result = this.state;

        if (this.state == null) {
            return result;
        }

        IState lastState = this.state;
        final int nextPriority = this.state.getPriority() + 1;
        for (IState s : this.states.getStates()) {

            final int priority = s.getPriority();
            if (priority == nextPriority) {

                MsgHelper.sendToDefaultReaders(new DebugMsg("Level.nextState: "
                        + priority));

                if (lastState != null) {
                    lastState.stop();
                }

                result = s;
                result.start(this.model);

                break;
            }
        }

        return result;
    }

    @Override
    public void setComplete(IComplete complete) {
        this.complete = complete;
    }

    @Override
    public void setHints(IHints hints) {
        this.hints = hints;
    }

    @Override
    public void setMessages(IMessages messages) {
        this.messages = messages;
    }

    @Override
    public void setStartup(IStartup startup) {

        this.startup = startup;
    }

    public void setStartup(Startup startup) {
        this.startup = startup;
    }

    @Override
    public void setStates(IStates states) {
        this.states = states;
    }

    @Override
    public void start(IContext model) {

        DebugMsg d = new DebugMsg("Level.start " + this.goal);
        MsgHelper.sendToDefaultReaders(d);

        this.model = model;
        this.startup.execute(model);
        this.messages.start(model);

        if (this.states.getStates().length > 0) {
            this.state = this.states.getStates()[0];
            this.state.start(model);
        }
    }

    @Override
    public void stop() {

        DebugMsg d = new DebugMsg("Level.stop");
        MsgHelper.sendToDefaultReaders(d);

        this.messages.stop();
    }

}
